﻿using Microsoft.UI;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using System;
using System.Configuration;
using System.IO;
using System.Runtime.InteropServices;
using Vanara.PInvoke;
using Windows.Graphics;
using Windows.Storage;
using Windows.UI;
using WinRT.Interop;
using static FASTControlUI.BackStyleControl;

namespace FASTControlUI
{
    internal class MainConfig
    {
        private Color lineColor = Colors.Blue;
        private BackStyleControl.FastStyle style;
        public Color LineColor { get { return lineColor; } set { lineColor = value; } }
        public BackStyleControl.FastStyle Style { get { return style; } set { style = value; } }
        static private MainConfig current;
        private Window window;
        private AppWindow appWindow;
        private Microsoft.UI.WindowId id;
        private IntPtr hwnd;
        BackStyleControl backStyleControl;
        ConfigManager<MainConfigData> configManager = new ConfigManager<MainConfigData>(ConfigManager<MainConfigData>.MainConfig);
        string SaveKey = "MainConfigData";
        MainConfig(Object window)
        {
            this.window = (Window)window;
            hwnd = WindowNative.GetWindowHandle(window);
            id = Win32Interop.GetWindowIdFromWindow(hwnd);
            appWindow = AppWindow.GetFromWindowId(id);
        }
        static public MainConfig Current
        {
            get { return current; }
        }
        static public MainConfig GetMainConfig(Object window)
        {
            if (current == null)
            {
                current = new MainConfig(window);
            }
            return current;
        }
        public AppWindow AppWindow { get { return appWindow; } }
        public IntPtr Hwnd { get { return hwnd; } }
        struct MainConfigData
        {
            public bool IsMainWindowMaximum;
            public ulong MainWindowRect;
            public uint LineColor;
            public FastStyle BackStyle;
        }
        public void ReadConfig()
        {
            MainConfigData configData = configManager[SaveKey];
            if (configData.IsMainWindowMaximum)
            {
                User32.ShowWindow(hwnd, ShowWindowCommand.SW_SHOWMAXIMIZED);
            }
            if (configData.MainWindowRect != 0)
            {
                var rect = new WindowRect(configData.MainWindowRect);
                // 屏幕区域
                var area = DisplayArea.GetFromWindowId(windowId: id, DisplayAreaFallback.Primary);
                // 若窗口在屏幕范围之内
                if (rect.Left > 0 && rect.Top > 0 && rect.Right < area.WorkArea.Width && rect.Bottom < area.WorkArea.Height)
                {
                    appWindow.MoveAndResize(rect.ToRectInt32());
                }
            }
            if (configData.LineColor != 0)
            {
                if (BitConverter.GetBytes(configData.LineColor) is byte[] color)
                {
                    lineColor = Color.FromArgb(color[0], color[1], color[2], color[3]);
                }
            }

            backStyleControl = new BackStyleControl(configData.BackStyle, ref window);
            backStyleControl.SetConfigurationSourceTheme(((FrameworkElement)window.Content).ActualTheme);
        }
        public void SaveConfig()
        {
            // 保存窗口状态
            backStyleControl.WindowsColose();
            MainConfigData configData = new MainConfigData();
            var wpl = new User32.WINDOWPLACEMENT();
            if (User32.GetWindowPlacement(hwnd, ref wpl))
            {
                configData.IsMainWindowMaximum = (wpl.showCmd == ShowWindowCommand.SW_MAXIMIZE);
                var p = appWindow.Position;
                var s = appWindow.Size;
                var rect = new WindowRect(p.X, p.Y, s.Width, s.Height);
                configData.MainWindowRect = rect.Value;
                byte[] color = new byte[4];
                color[0] = lineColor.A; color[1] = lineColor.R; color[2] = lineColor.G; color[3] = lineColor.B;
                configData.LineColor = BitConverter.ToUInt32(color);
                configData.BackStyle = style;
                configManager[SaveKey] = configData;
            }
        }
        public void SetStyle(BackStyleControl.FastStyle fastSytle)
        {
            style = fastSytle;
            backStyleControl.WindowsColose();
            backStyleControl = new BackStyleControl(fastSytle, ref window);
        }
        public BackStyleControl HomeStyle
        {
            get { return backStyleControl; }
        }

        [StructLayout(LayoutKind.Explicit)]
        private struct WindowRect
        {
            [FieldOffset(0)]
            public short X;
            [FieldOffset(2)]
            public short Y;
            [FieldOffset(4)]
            public short Width;
            [FieldOffset(6)]
            public short Height;
            [FieldOffset(0)]
            public ulong Value;

            public int Left => X;
            public int Top => Y;
            public int Right => X + Width;
            public int Bottom => Y + Height;

            public WindowRect(int x, int y, int width, int height)
            {
                Value = 0;
                X = (short)x;
                Y = (short)y;
                Width = (short)width;
                Height = (short)height;
            }

            public WindowRect(ulong value)
            {
                X = Y = Width = Height = 0;
                Value = value;
            }

            public RectInt32 ToRectInt32()
            {
                return new RectInt32(X, Y, Width, Height);
            }
        }
    }
}
